"""
症状自查小程序 - Python API客户端
提供完整的API调用功能，包括用户认证、症状查询、诊断分析等
"""

import requests
import json
import os
from typing import Dict, List, Optional
from datetime import datetime
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class SymptomCheckerAPI:
    """症状自查小程序API客户端"""
    
    def __init__(self, base_url: str = "https://api.symptom-checker.com/v1"):
        """
        初始化API客户端
        
        Args:
            base_url: API基础URL，默认为官方地址
        """
        self.base_url = base_url.rstrip('/')
        self.token = None
        self.session = requests.Session()
        
        # 配置会话
        self.session.headers.update({
            'User-Agent': 'SymptomChecker-Python-Client/1.0.0'
        })
        
        logger.info(f"API客户端初始化完成，基础URL: {self.base_url}")
    
    def _get_headers(self) -> Dict[str, str]:
        """获取请求头"""
        headers = {
            "Content-Type": "application/json"
        }
        if self.token:
            headers["Authorization"] = f"Bearer {self.token}"
        return headers
    
    def _make_request(self, method: str, endpoint: str, data: Optional[Dict] = None, 
                     params: Optional[Dict] = None) -> Dict:
        """
        发送HTTP请求
        
        Args:
            method: HTTP方法 (GET, POST, DELETE等)
            endpoint: API端点路径
            data: 请求体数据
            params: URL参数
            
        Returns:
            响应数据字典
            
        Raises:
            requests.exceptions.RequestException: 请求失败时抛出
        """
        url = f"{self.base_url}{endpoint}"
        headers = self._get_headers()
        
        logger.debug(f"发送{method}请求到: {url}")
        
        try:
            response = self.session.request(
                method=method.upper(),
                url=url,
                headers=headers,
                json=data,
                params=params,
                timeout=30
            )
            response.raise_for_status()
            
            result = response.json()
            logger.debug(f"请求成功: {result.get('code', '未知状态码')}")
            return result
            
        except requests.exceptions.Timeout:
            logger.error("请求超时")
            raise
        except requests.exceptions.HTTPError as e:
            logger.error(f"HTTP错误: {e.response.status_code}")
            raise
        except requests.exceptions.RequestException as e:
            logger.error(f"请求异常: {e}")
            raise
    
    def login(self, username: str, password: str, user_type: str = "client") -> bool:
        """
        用户登录
        
        Args:
            username: 用户名
            password: 密码
            user_type: 用户类型 (client|doctor)
            
        Returns:
            登录是否成功
        """
        data = {
            "username": username,
            "password": password,
            "user_type": user_type
        }
        
        logger.info(f"用户登录: {username} ({user_type})")
        
        try:
            result = self._make_request("POST", "/auth/login", data)
            
            if result.get("code") == 200:
                self.token = result["data"]["token"]
                user_id = result["data"]["user_id"]
                logger.info(f"登录成功，用户ID: {user_id}")
                return True
            else:
                error_msg = result.get('message', '未知错误')
                logger.error(f"登录失败: {error_msg}")
                return False
                
        except Exception as e:
            logger.error(f"登录过程异常: {e}")
            return False
    
    def register(self, username: str, password: str, email: str, 
                user_type: str = "client", doctor_license: Optional[str] = None) -> bool:
        """
        用户注册
        
        Args:
            username: 用户名
            password: 密码
            email: 邮箱
            user_type: 用户类型 (client|doctor)
            doctor_license: 医护端需要的执照编号
            
        Returns:
            注册是否成功
        """
        data = {
            "username": username,
            "password": password,
            "email": email,
            "user_type": user_type
        }
        
        if user_type == "doctor" and doctor_license:
            data["doctor_license"] = doctor_license
        
        logger.info(f"用户注册: {username} ({user_type})")
        
        try:
            result = self._make_request("POST", "/auth/register", data)
            
            if result.get("code") == 200:
                user_id = result["data"]["user_id"]
                logger.info(f"注册成功，用户ID: {user_id}")
                return True
            else:
                error_msg = result.get('message', '未知错误')
                logger.error(f"注册失败: {error_msg}")
                return False
                
        except Exception as e:
            logger.error(f"注册过程异常: {e}")
            return False
    
    def get_symptoms(self, category: Optional[str] = None) -> List[Dict]:
        """
        获取症状列表
        
        Args:
            category: 症状分类，可选
            
        Returns:
            症状列表
        """
        params = {}
        if category:
            params["category"] = category
        
        logger.info(f"获取症状列表，分类: {category or '全部'}")
        
        try:
            result = self._make_request("GET", "/symptoms", params=params)
            
            if result.get("code") == 200:
                symptoms = result["data"]["symptoms"]
                logger.info(f"获取到 {len(symptoms)} 个症状")
                return symptoms
            else:
                logger.error(f"获取症状列表失败")
                return []
                
        except Exception as e:
            logger.error(f"获取症状列表异常: {e}")
            return []
    
    def diagnose(self, selected_symptoms: List[str], user_id: str, 
                additional_info: str = "") -> Dict:
        """
        提交症状进行诊断
        
        Args:
            selected_symptoms: 选择的症状ID列表
            user_id: 用户ID
            additional_info: 附加信息
            
        Returns:
            诊断结果
        """
        data = {
            "selected_symptoms": selected_symptoms,
            "user_id": user_id,
            "additional_info": additional_info
        }
        
        logger.info(f"提交诊断，用户: {user_id}, 症状数: {len(selected_symptoms)}")
        
        try:
            result = self._make_request("POST", "/diagnosis", data)
            
            if result.get("code") == 200:
                diagnosis_data = result["data"]
                logger.info(f"诊断完成，可能疾病: {diagnosis_data.get('possible_conditions', [])}")
                return diagnosis_data
            else:
                logger.error(f"诊断失败")
                return {}
                
        except Exception as e:
            logger.error(f"诊断过程异常: {e}")
            return {}
    
    def get_diagnosis_history(self, user_id: str) -> List[Dict]:
        """
        获取诊断历史
        
        Args:
            user_id: 用户ID
            
        Returns:
            诊断历史记录列表
        """
        params = {"user_id": user_id}
        
        logger.info(f"获取诊断历史，用户: {user_id}")
        
        try:
            result = self._make_request("GET", "/diagnosis/history", params=params)
            
            if result.get("code") == 200:
                records = result["data"]["records"]
                logger.info(f"获取到 {len(records)} 条诊断记录")
                return records
            else:
                logger.error(f"获取诊断历史失败")
                return []
                
        except Exception as e:
            logger.error(f"获取诊断历史异常: {e}")
            return []
    
    def get_statistics(self) -> Dict:
        """
        获取诊断统计（医护端）
        
        Returns:
            统计数据
        """
        logger.info("获取诊断统计")
        
        try:
            result = self._make_request("GET", "/statistics/diagnosis")
            
            if result.get("code") == 200:
                stats = result["data"]
                logger.info(f"统计获取成功，总诊断数: {stats.get('total_diagnoses', 0)}")
                return stats
            else:
                logger.error(f"获取统计失败")
                return {}
                
        except Exception as e:
            logger.error(f"获取统计异常: {e}")
            return {}


class AdvancedSymptomCheckerAPI(SymptomCheckerAPI):
    """高级API客户端，提供批量操作和导出功能"""
    
    def __init__(self, base_url: Optional[str] = None):
        """
        初始化高级API客户端
        
        Args:
            base_url: API基础URL，如果为None则从环境变量读取
        """
        if base_url is None:
            base_url = os.getenv("SYMPTOM_CHECKER_API_URL", "https://api.symptom-checker.com/v1")
        
        super().__init__(base_url)
    
    def batch_diagnose(self, user_symptoms_list: List[Dict]) -> List[Dict]:
        """
        批量诊断多个用户
        
        Args:
            user_symptoms_list: 用户症状数据列表，每个元素包含:
                - user_id: 用户ID
                - symptoms: 症状ID列表
                - additional_info: 附加信息（可选）
            
        Returns:
            批量诊断结果列表
        """
        results = []
        
        logger.info(f"开始批量诊断，用户数: {len(user_symptoms_list)}")
        
        for i, user_data in enumerate(user_symptoms_list, 1):
            try:
                result = self.diagnose(
                    user_data["symptoms"],
                    user_data["user_id"],
                    user_data.get("additional_info", "")
                )
                
                results.append({
                    "user_id": user_data["user_id"],
                    "result": result,
                    "timestamp": datetime.now().isoformat(),
                    "status": "success"
                })
                
                logger.info(f"批量诊断进度: {i}/{len(user_symptoms_list)}")
                
            except Exception as e:
                logger.error(f"用户 {user_data['user_id']} 诊断失败: {e}")
                results.append({
                    "user_id": user_data["user_id"],
                    "result": {},
                    "timestamp": datetime.now().isoformat(),
                    "status": "failed",
                    "error": str(e)
                })
        
        success_count = len([r for r in results if r["status"] == "success"])
        logger.info(f"批量诊断完成，成功: {success_count}, 失败: {len(results) - success_count}")
        
        return results
    
    def export_diagnosis_history(self, user_id: str, filename: str, 
                               format_type: str = "json") -> bool:
        """
        导出诊断历史到文件
        
        Args:
            user_id: 用户ID
            filename: 输出文件名
            format_type: 导出格式 (json|csv)
            
        Returns:
            导出是否成功
        """
        history = self.get_diagnosis_history(user_id)
        
        if not history:
            logger.warning("没有诊断历史可导出")
            return False
        
        try:
            if format_type.lower() == "json":
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(history, f, ensure_ascii=False, indent=2)
            
            elif format_type.lower() == "csv":
                import csv
                with open(filename, 'w', encoding='utf-8', newline='') as f:
                    writer = csv.writer(f)
                    # 写入表头
                    writer.writerow(['诊断ID', '症状', '诊断结果', '时间'])
                    
                    for record in history:
                        writer.writerow([
                            record.get('id', ''),
                            ', '.join(record.get('selected_symptoms', [])),
                            record.get('diagnosis_result', {}).get('possible_conditions', [''])[0],
                            record.get('timestamp', '')
                        ])
            
            else:
                logger.error(f"不支持的导出格式: {format_type}")
                return False
            
            logger.info(f"诊断历史已导出到: {filename} (格式: {format_type})")
            return True
            
        except Exception as e:
            logger.error(f"导出失败: {e}")
            return False
    
    def search_symptoms_by_keyword(self, keyword: str) -> List[Dict]:
        """
        根据关键词搜索症状
        
        Args:
            keyword: 搜索关键词
            
        Returns:
            匹配的症状列表
        """
        all_symptoms = self.get_symptoms()
        
        if not all_symptoms:
            return []
        
        # 简单的关键词匹配（实际项目中可以使用更复杂的搜索算法）
        matched_symptoms = []
        
        for symptom in all_symptoms:
            name = symptom.get('name', '').lower()
            description = symptom.get('description', '').lower()
            keyword_lower = keyword.lower()
            
            if (keyword_lower in name or keyword_lower in description):
                matched_symptoms.append(symptom)
        
        logger.info(f"关键词 '{keyword}' 搜索到 {len(matched_symptoms)} 个症状")
        return matched_symptoms


def main():
    """使用示例"""
    
    # 基础使用示例
    print("=== 基础API使用示例 ===")
    
    # 创建API客户端
    api = SymptomCheckerAPI()
    
    # 用户登录（这里使用模拟数据）
    if api.login("test_user", "password123"):
        # 获取症状列表
        symptoms = api.get_symptoms()
        print(f"获取到 {len(symptoms)} 个症状")
        
        # 显示前几个症状
        for i, symptom in enumerate(symptoms[:3], 1):
            print(f"{i}. {symptom.get('name')} - {symptom.get('description')}")
        
        # 进行诊断
        selected_symptoms = ["fever", "cough"]  # 假设的症状ID
        diagnosis_result = api.diagnose(selected_symptoms, "user_123")
        
        if diagnosis_result:
            print(f"\n诊断结果:")
            print(f"可能疾病: {', '.join(diagnosis_result.get('possible_conditions', []))}")
            print(f"概率: {diagnosis_result.get('probability', 0)}")
            print(f"建议: {diagnosis_result.get('advice', '')}")
        
        # 获取诊断历史
        history = api.get_diagnosis_history("user_123")
        print(f"\n诊断历史记录数: {len(history)}")
    
    print("\n=== 高级API使用示例 ===")
    
    # 高级API使用
    advanced_api = AdvancedSymptomCheckerAPI()
    
    # 批量诊断示例
    users_data = [
        {"user_id": "user1", "symptoms": ["fever", "cough"]},
        {"user_id": "user2", "symptoms": ["headache", "fatigue"]}
    ]
    
    batch_results = advanced_api.batch_diagnose(users_data)
    print(f"批量诊断完成，共处理 {len(batch_results)} 个用户")
    
    # 关键词搜索示例
    matched_symptoms = advanced_api.search_symptoms_by_keyword("头痛")
    print(f"关键词搜索到 {len(matched_symptoms)} 个相关症状")


if __name__ == "__main__":
    main()